﻿using System;
using System.Collections.Generic;
using UnityEngine;
using Tobii.Gaming;
using ProcessHandles;

public struct ParticipatedRecord
{
    public string s_StimulusGroupIdx;
    public SortedSet<string> particippatedList;
}

public struct SerializableGazePoint
{
    //超属性
    public string StimulusIdx;

    //GazePoint原生属性
    public Vector2 Viewport;
    public Vector2 Screen;
    public Vector2 GUI;
    public bool IsValid;
    public float Timestamp;
    public long PreciseTimestamp;
}

public struct SerializableCfgInfo
{
    //CfgInfo原生属性
    public float s_ImageDuration;
    public float s_IntvDuration;

    public int s_CountDown;
    public int s_Frequency;

    public string s_StimulusGroupIdx;
    public List<string> s_StimulusIdxList;
}

public struct SerializableParticipantInfo
{
    //CfgInfo原生属性
    public string s_Index;
    public string s_Name;
    public float s_Age;
    public bool s_IsMale;
    public bool s_IsASD;
}

public class Serializer
{
    //参与者记录列表
    public static ParticipatedRecord[] records = null;

    //收集到原始注视点
    public static List<GazePoint> GazePoints = new List<GazePoint>();


    //收集到原始注视点，每个点对应的图片编号
    public static List<string> ImageIdxOfGazePoints = new List<string>();


    //序列化IO的中转对象
    public static SerializableCfgInfo serializableCfgInfo;
    public static SerializableParticipantInfo serializableParticipantInfo;

    //列表数组，存放每张图片的注视点。一项代表一张图片的点列表
    public static List<Vector3>[] ss;

    public static bool Serialize()
    {
        serializableParticipantInfo.s_Index = Participant_Info.s_Index;
        serializableParticipantInfo.s_Name = Participant_Info.s_Name;
        serializableParticipantInfo.s_Age = Participant_Info.s_Age;
        serializableParticipantInfo.s_IsASD = Participant_Info.s_IsASD;
        serializableParticipantInfo.s_IsMale = Participant_Info.s_IsMale;

        serializableCfgInfo.s_CountDown = Cfg_Info.s_CountDown;
        serializableCfgInfo.s_Frequency = Cfg_Info.s_Frequency;
        serializableCfgInfo.s_IntvDuration = Cfg_Info.s_IntvDuration;
        serializableCfgInfo.s_ImageDuration = Cfg_Info.s_ImageDuration;
        serializableCfgInfo.s_StimulusGroupIdx = Cfg_Info.s_StimulusGroupIdx;
        serializableCfgInfo.s_StimulusIdxList = Cfg_Info.s_StimulusIdxList;

        DataIO.fileBuffer.Clear();
        DataIO.fileBuffer.Add(JsonUtility.ToJson(serializableParticipantInfo));
        DataIO.fileBuffer.Add(JsonUtility.ToJson(serializableCfgInfo));

        InitSS();
        int k = 0;
        Transform imageDisplay = GameObject.FindObjectOfType<Controller>().ImageDisplay.transform;

        for (int i = 0; i < GazePoints.Count; i++)
        {
            GazePoint g = GazePoints[i];
            SerializableGazePoint gs;

            gs.StimulusIdx = ImageIdxOfGazePoints[i];
            gs.Viewport = g.Viewport;
            gs.Screen = g.Screen;
            gs.GUI = g.GUI;
            gs.IsValid = g.IsValid;
            gs.Timestamp = g.Timestamp;
            gs.PreciseTimestamp = g.PreciseTimestamp;

            DataIO.fileBuffer.Add(JsonUtility.ToJson(gs));

            Vector3 p = imageDisplay.InverseTransformPoint(Camera.main.ScreenToWorldPoint(gs.Screen));
            p.z = 0f;

            if (gs.StimulusIdx == serializableCfgInfo.s_StimulusIdxList[k])
            {
                ss[k].Add(p);
            }
            else
            {
                ss[++k].Add(p);
            }
        }

        DataIO.WriteSerializedData();

        GazePoints.Clear();
        ImageIdxOfGazePoints.Clear();

        return true;
    }

    public static bool GetFromJson(string path)
    {
        DataIO.ReadOutTxt(path);

        serializableParticipantInfo = JsonUtility.FromJson<SerializableParticipantInfo>(DataIO.fileBuffer[0]);
        serializableCfgInfo.s_StimulusIdxList =  new List<string>();
        serializableCfgInfo = JsonUtility.FromJson<SerializableCfgInfo>(DataIO.fileBuffer[1]);

        InitSS();

        Transform imageDisplay = GameObject.FindObjectOfType<Controller>().ImageDisplay.transform;

        int k = 0;
        for(int i = 2; i < DataIO.fileBuffer.Count; i++)
        {
            SerializableGazePoint gs;
            gs = JsonUtility.FromJson<SerializableGazePoint>(DataIO.fileBuffer[i]);

            //把注视点坐标转换为对图片的相对坐标
            Vector3 p = imageDisplay.InverseTransformPoint(Camera.main.ScreenToWorldPoint(gs.Screen));
            p.z = 0f;

            if (gs.StimulusIdx == serializableCfgInfo.s_StimulusIdxList[k])
            {
                ss[k].Add(p);
            }
            else
            {
                ss[++k].Add(p);
            }
        }

        return true;
    }

    public static void AddParticipant()
    {
        if(records == null)
        {
            LoadRecords();
        }

        DataIO.fileBuffer.Clear();

        foreach (var re in records)
        {
            string buffer = re.s_StimulusGroupIdx + "@";

            if (re.s_StimulusGroupIdx == Cfg_Info.s_StimulusGroupIdx)
            {
                re.particippatedList.Add(Participant_Info.s_Index);
            }

            foreach (var idx in re.particippatedList)
            {
                buffer += idx + ",";
            }
            DataIO.fileBuffer.Add(buffer);
            //Debug.Log(buffer);
        }
        DataIO.WriteIntoTxt();

    }

    public static void LoadRecords()
    {
        List<string> fileBuffer = DataIO.ReadOutTxt();
        Serializer.records = new ParticipatedRecord[fileBuffer.Count];

        for (int i = 0; i < fileBuffer.Count; i++)
        {
            //Debug.Log(fileBuffer[i]);
            var d = fileBuffer[i].Split('@');
            Serializer.records[i].s_StimulusGroupIdx = d[0];
            Serializer.records[i].particippatedList = new SortedSet<string>();

            d = d[1].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            for (int j = 0; j < d.Length; j++)
            {
                Serializer.records[i].particippatedList.Add(d[j]);
            }
        }
    }

    public static string GetProperStimulsbyPatIdx()
    {
        return "";
    }

    private static void InitSS()
    {
        if (ss == null) ss = new List<Vector3>[serializableCfgInfo.s_StimulusIdxList.Count];

        for (int i = 0; i < ss.Length; i++)
        {
            if (ss[i] == null) ss[i] = new List<Vector3>();
            else ss[i].Clear();
        }

    }

}


